﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using Excel = Microsoft.Office.Interop.Excel;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
using Constants;
using OAuthProtocol;
using Dropbox.Api;
using System.Reflection;
using LoadingClass;





namespace Budget
{
    public partial class FormMain : Form
    {
        DataSet m_BudgetDataSet;
        DropboxApi m_DropboxApi;

        public FormMain()
        {

            AppDomain.CurrentDomain.AssemblyResolve += (sender,args) => 
            {
                string resourseName = new AssemblyName(args.Name).Name + ".dll";
                string resource = Array.Find(this.GetType().Assembly.GetManifestResourceNames(), element => element.EndsWith(resourseName));

                using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
                {
                    Byte[] assemblyData = new Byte[stream.Length];
                    stream.Read(assemblyData, 0, assemblyData.Length);
                    return Assembly.Load(assemblyData);
                }
            };

            
            InitializeComponent();
            afterInitializeActions();
        }

        void afterInitializeActions()
        {
            m_BudgetDataSet = new DataSet();

            var consumerKey = "dv0twf1afhw2jn0";
            var consumerSecret = "ni23fzhr70lszai";
            var token = "pc3cry6a5qhn4guj";
            var secret = "6906coav4gkrtms";
            OAuthToken accessToken = new OAuthToken(token, secret);

            m_DropboxApi = new DropboxApi(consumerKey, consumerSecret, accessToken);

            LoadingClass.BackgroundLoading BL = new LoadingClass.BackgroundLoading(GetExpenseDataSet, "Loading");
            BL.Start();
        }





        private void GetExpenseDataSet()
        {
            var file = m_DropboxApi.DownloadFile("dropbox", @"PazGonen/Budget/DataFiles/Expenses - Copy.xml");

            XmlDocument doc = new XmlDocument();
            MemoryStream ms = new MemoryStream(file.Data);
            doc.Load(ms);

            XmlReader reader = new XmlNodeReader(doc);

            DataSet tmpExpenseDataSet = new DataSet();
            tmpExpenseDataSet.ReadXml(reader);

            //tmpExpenseDataSet.Tables.Add(Tables.Income);
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("Date", System.Type.GetType("System.DateTime"));
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("Amount", System.Type.GetType("System.Double"));
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("User", System.Type.GetType("System.String"));
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("Category", System.Type.GetType("System.String"));
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("Type", System.Type.GetType("System.String"));
            //tmpExpenseDataSet.Tables[Tables.Income].Columns.Add("Description", System.Type.GetType("System.String"));

            
            DataTable incomeDataTable = new DataTable(Tables.Income);
            incomeDataTable = tmpExpenseDataSet.Tables[1].Clone();
            
            incomeDataTable.Columns[Fields.Date].DataType = System.Type.GetType("System.DateTime");
            incomeDataTable.Columns[Fields.Amount].DataType = System.Type.GetType("System.Double");
            
            //DataRow bla = incomeDataTable.NewRow();
            //bla[0] = DateTime.Parse("21/10/2014");
            //bla[1] = 457;
            //bla[2] = "Refael";
            //bla[3] = "Salary";
            //bla[4] = "Bank Transfer";
            //bla[5] = "GreenHouse";
            //incomeDataTable.Rows.Add(bla);



            foreach (DataRow row in tmpExpenseDataSet.Tables[Tables.Income].Rows)
            {
                DataRow tmpDataRow = incomeDataTable.NewRow();
                tmpDataRow[Fields.Date] = DateTime.Parse(row[Fields.Date].ToString());
                tmpDataRow[Fields.Amount] = Double.Parse(row[Fields.Amount].ToString());
                tmpDataRow[Fields.User] = row[Fields.User];
                tmpDataRow[Fields.Category] = row[Fields.Category];
                tmpDataRow[Fields.Type] = row[Fields.Type];
                tmpDataRow[Fields.Description] = row[Fields.Description];
                incomeDataTable.Rows.Add(tmpDataRow);
            }

            DataTable expenseDataTable = new DataTable(Tables.Expenses);
            expenseDataTable = tmpExpenseDataSet.Tables[0].Clone();

            expenseDataTable.Columns[Fields.Date].DataType = System.Type.GetType("System.DateTime");
            expenseDataTable.Columns[Fields.Amount].DataType = System.Type.GetType("System.Double");

            foreach (DataRow row in tmpExpenseDataSet.Tables[0].Rows)
            {
                DataRow tmpDataRow = expenseDataTable.NewRow();
                tmpDataRow[Fields.Date] = DateTime.Parse(row[Fields.Date].ToString());
                tmpDataRow[Fields.Amount] = Double.Parse(row[Fields.Amount].ToString());
                tmpDataRow[Fields.Shared] = row[Fields.Shared];
                tmpDataRow[Fields.User] = row[Fields.User];
                tmpDataRow[Fields.Category] = row[Fields.Category];
                tmpDataRow[Fields.Description] = row[Fields.Description];
                expenseDataTable.Rows.Add(tmpDataRow);
            }

            m_BudgetDataSet.Tables.Add(expenseDataTable);
            m_BudgetDataSet.Tables.Add(incomeDataTable);
        }

        private void FormMain_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.Visible = false;
            LoadingClass.BackgroundLoading BL = new LoadingClass.BackgroundLoading(UploadExpenseToDropbox, "Quiting");
            BL.Start();
        }

        private void UploadExpenseToDropbox()
        {
            MemoryStream memory = new MemoryStream();
            XmlWriter expenseData = XmlWriter.Create(memory);
            m_BudgetDataSet.WriteXml(expenseData);
            m_DropboxApi.UploadFile("dropbox", @"PazGonen/Budget/DataFiles/Expenses - Copy.xml", memory);
        }

        private void buttonOpenQV_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process.Start(System.Environment.CurrentDirectory + @"\Expenses.qvw");
        }

        private void buttonQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void buttonAddExpense_Click(object sender, EventArgs e)
        {
            CheckIfDropboxIsRunning();
            FormExpense formExpense = new FormExpense(ref m_BudgetDataSet);
            this.Visible = false;
            formExpense.Location = this.DesktopLocation;
            formExpense.ShowDialog();
            this.Visible = true;
        }

        private void buttonAddIncome_Click(object sender, EventArgs e)
        {
            CheckIfDropboxIsRunning();
            FormIncome formIncome = new FormIncome(ref m_BudgetDataSet);
            this.Visible = false;
            formIncome.Location = this.DesktopLocation;
            formIncome.ShowDialog();
            this.Visible = true;
        }


        private void CheckIfDropboxIsRunning()
        {
            if (!IsProcessRunning("Dropbox"))
            {
                string msg = "Dropbox is not running\n Would you like to open it?";
                DialogResult result = MessageBox.Show(msg, "Open Dropbox?", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (result == DialogResult.Yes)
                {
                    Process.Start(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData) + @"\Dropbox\bin\Dropbox.exe");
                }
            }
        }

        private void buttonModifyData_Click(object sender, EventArgs e)
        {
            this.Visible = false;
            FormData formData = new FormData(ref m_BudgetDataSet);
            formData.ShowDialog();
            this.Visible = true;
        }

        private bool IsProcessRunning(string i_processName)
        {
            foreach (Process process in Process.GetProcesses())
            {
                if (process.ProcessName.Contains(i_processName))
                {
                    return true;
                }
            }
            return false;
        }

        //Button Add Expense
        private void buttonAddExpense_MouseEnter(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddExpense_MouseOn;
        }

        private void buttonAddExpense_MouseLeave(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.IconAddExpense;
        }

        private void buttonAddExpense_MouseDown(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddExpense_MouseClick;
            (sender as Button).SetBounds((sender as Button).Location.X + 7, (sender as Button).Location.Y + 5, (sender as Button).Width, (sender as Button).Height);
        }

        private void buttonAddExpense_MouseUp(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddExpense_MouseOn;
            (sender as Button).SetBounds((sender as Button).Location.X - 7, (sender as Button).Location.Y - 5, (sender as Button).Width, (sender as Button).Height);
        }
        
        //Button Add Income
        private void buttonAddIncome_MouseEnter(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddIncome_MouseOn;
        }

        private void buttonAddIncome_MouseLeave(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.IconAddIncome;
        }

        private void buttonAddIncome_MouseDown(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddIncome_MouseClick;
            (sender as Button).SetBounds((sender as Button).Location.X + 7, (sender as Button).Location.Y + 5, (sender as Button).Width, (sender as Button).Height);
        }

        private void buttonAddIncome_MouseUp(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.AddIncome_MouseOn;
            (sender as Button).SetBounds((sender as Button).Location.X - 7, (sender as Button).Location.Y - 5, (sender as Button).Width, (sender as Button).Height);
        }

        //Button Quit
        private void buttonQuit_MouseEnter(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Quit_MouseOn_01;
        }

        private void buttonQuit_MouseLeave(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Quit_01;
        }

        private void buttonQuit_MouseDown(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Quit_MouseClick_01;
            (sender as Button).SetBounds((sender as Button).Location.X + 3, (sender as Button).Location.Y + 2, (sender as Button).Width - 5, (sender as Button).Height - 5);
        }

        private void buttonQuit_MouseUp(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Quit_MouseOn_01;
            (sender as Button).SetBounds((sender as Button).Location.X - 3, (sender as Button).Location.Y - 2, (sender as Button).Width + 5, (sender as Button).Height + 5);
        }

        //Button Open QV
        private void buttonOpenQV_MouseEnter(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.OpenQV_MouseOn;
        }

        private void buttonOpenQV_MouseLeave(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.IconOpenQV;
        }

        private void buttonOpenQV_MouseDown(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.OpenQV_MouseClick_01;
            (sender as Button).SetBounds((sender as Button).Location.X + 7, (sender as Button).Location.Y + 3, (sender as Button).Width, (sender as Button).Height);
            (sender as Button).Width = (sender as Button).Width - 8;
            (sender as Button).Height = (sender as Button).Height - 8;
        }

        private void buttonOpenQV_MouseUp(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.OpenQV_MouseOn;
            (sender as Button).SetBounds((sender as Button).Location.X - 7, (sender as Button).Location.Y - 3, (sender as Button).Width, (sender as Button).Height);
            (sender as Button).Width = (sender as Button).Width + 8;
            (sender as Button).Height = (sender as Button).Height + 8;
        }

        //Button Modify
        private void buttonModifyData_MouseEnter(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Modify_MouseOn_01;
        }

        private void buttonModifyData_MouseLeave(object sender, EventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Modify_01;
        }

        private void buttonModifyData_MouseDown(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Modify_MouseClick01;
            (sender as Button).SetBounds((sender as Button).Location.X + 5, (sender as Button).Location.Y + 2, (sender as Button).Width - 5, (sender as Button).Height - 5);
        }

        private void buttonModifyData_MouseUp(object sender, MouseEventArgs e)
        {
            (sender as Button).BackgroundImage = Properties.Resources.Modify_MouseOn_01;
            (sender as Button).SetBounds((sender as Button).Location.X - 5, (sender as Button).Location.Y - 2, (sender as Button).Width + 5, (sender as Button).Height + 5);
        }
    }
}
